<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*
        2.状态标记
     */

    // 2.1 初始代码
    const o = {};
    try {
        Object.defineProperty(o, 'foo', 'bar');
        console.log('success')
    } catch (e) {
        console.log('failure')
    }
    // 上面代码异常了,抛出错误,failure
    
    // 2.2 使用Reflect.defineProperty()
        // -失败的时候会返回false
    if(Reflect.defineProperty(o,'foo',{value:'bar'})){
        console.log('success')
    }else {
        console.log('failure')
    }
    
    // 2.4还有其他方法
/*    Reflect.defineProperty()
    Reflect.preventExtensions()
    Reflect.setPrototypeOf()
    Reflect.set()
    Reflect.deleteProperty()*/
    
    
    /*
        3.用一等函数替代操作符
     */
    let obj = {
        name:'张三'
    }
    Reflect.get(obj,'name') // 可以替代对象属性访问操作符
    Reflect.set(obj,name,'李四') // 可以替代=赋值操作符
    Reflect.has(obj,'name') // 可以替代in操作符或with()
    Reflect.deleteProperty(obj,'name') // 可以替代delete操作符
    // Reflect.construct() // 可以替代new操作符
    
    /*
        4.安全地应用函数
     */
    // 在通过apply方法调用函数时,被调用的函数可能也定义了自己的apply属性
    // 为了绕过这个问题,可以使用定义在Function原型上的apply方法
    // Function.prototype.apply.call(myFunc,thisVal,arguments)
    
    // 可以使用Reflect.apply来避免
    // Reflect.apply(myFunc,thisVal,arguments)
    
</script>
</body>
</html>